<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Chaplin Test Runner</title>
    <script src="bower_components/benchmark/benchmark.js"></script>
    <script src="bower_components/requirejs/require.js"></script>
    <script>
      requirejs.config({
        baseUrl: 'temp/',
        paths: {
          // jquery: '../bower_components/jquery/jquery',
          // underscore: '../bower_components/lodash/dist/lodash.compat',
          backbone: '../bower_components/exoskeleton/exoskeleton'
        },
        // For easier development, disable browser caching
        urlArgs: 'bust=' + (new Date()).getTime()
      });

      define('jquery', function(){});
      define('underscore', ['backbone'], function(Backbone){
        return Backbone.utils;
      });

      require(['chaplin'], function(Chaplin) {
        var log = function() {
          this.forEach(function(item) {
            console.log(item.name, Math.round(item.hz));
          });
        };

        var suiteBench = function(cases) {
          var suite = new Benchmark.Suite;
          Object.keys(cases).forEach(function(name) {
            var fn = cases[name];
            suite.add(name, fn);
          });
          return suite
            .on('error', function(e) {
              console.error('Error!', e);
            })
            .on('complete', log);
        };

        var bench = function(title, dict) {
          var paragraphs = Object.keys(dict).map(function(name) {
            var start = Date.now();
            dict[name]();
            return {name: name, time: Date.now() - start};
          }).map(function(item) {
            return item.name + ': ' + item.time + 'ms'
          });
          var insert = function(html) {
            document.body.insertAdjacentHTML('afterbegin', '<p>' + html + '</p>');
          };
          paragraphs.forEach(insert)
          insert('<h3>' + title + '</h3>');
        };

        var collectionBench = function() {
          var models = [];
          for (var code = 65; code <= 1565; code++) {
            models.push({
              id: code,
              char: String.fromCharCode(code),
              title: String(Math.random()).slice(2)
            });
          }

          var BaseItemView = Chaplin.View.extend({
            tagName: 'li',
            attributes: function() {
              var m = this.model;
              return {className: m.char, 'data-cid': m.cid};
            },
            template: function(data) {
              return data.char + ' - ' + data.title;
            },
            getTemplateFunction: function() {
              return this.template;
            }
          });

          var View = Chaplin.CollectionView.extend({
            animationDuration: 0,
            container: document.body,
            itemView: BaseItemView
          });

          var items = {
            50: new Chaplin.Collection(models.slice(0, 50)),
            100: new Chaplin.Collection(models.slice(50, 150)),
            200: new Chaplin.Collection(models.slice(150, 350)),
            500: new Chaplin.Collection(models.slice(0, 500)),
            1500: new Chaplin.Collection(models)
          };

          bench('Rendering collection views', {
            '50 items': function() {
              new View({collection: items['50'], className: '50'});
            },
            '100 items': function() {
              new View({collection: items['100'], className: '100'});
            },
            '200 items': function() {
              new View({collection: items['200'], className: '200'});
            },
            '500 items': function() {
              new View({collection: items['500'], className: '500'});
            },
            '1500 items': function() {
              new View({collection: items['1500'], className: '1500'});
            }
          });
        };

        var router = new Chaplin.Router;
        router.match('index', 'null#1', {name: 'home'});
        router.match('phone/:one', 'null#2', {name: 'phonebook'});
        router.match('params/:two', 'null#3', {name: 'about'});
        router.match('fake/:three', 'fake#2', {name: 'about'});
        router.match('phone/:four', 'null#a');

        var routerBench = suiteBench({
          object: function() {
            Chaplin.utils.reverse('null#a', {four: 1});
          },
          list: function() {
            Chaplin.utils.reverse('null#a', [1]);
          }
        });

        collectionBench();
        routerBench.run({async: true});
      });
    </script>
  </head>
  <body>
    <div id="mocha"></div>
    <div id="testbed"></div>
  </body>
</html>
